package ieureka

import (
	"gitee.com/tietang/terrace-go/v2/base"
	"gitee.com/tietang/terrace-go/v2/base/starter/iiris"
	"github.com/kataras/iris/v12"
	"github.com/tietang/go-eureka-client/eureka"
	"github.com/tietang/go-eureka-client/eureka/config"
	"github.com/tietang/props/v3/kvs"
	"syscall"
	"time"
)

var eurekaClient *eureka.Client

func EurekaClient() *eureka.Client {
	base.Check(eurekaClient)
	return eurekaClient
}

type EurekaStarter struct {
	base.BaseStarter
	client *eureka.Client
}

func (s *EurekaStarter) Init(ctx base.StarterContext) {
	s.client = NewEurekaClient(ctx.Props())
	//data, _ := json.Marshal(s.client.InstanceInfo)
	//fmt.Println(string(data))
	s.client.InstanceConfig.InitialStatus = config.STARTING
	s.client.InstanceInfo.Status = eureka.StatusStarting
	//data, _ := json.Marshal(s.client.InstanceInfo)
	//fmt.Println(string(data))
	eurekaClient = s.client
	s.client.Start()
	//data, _ = json.Marshal(s.client.InstanceInfo)
	//fmt.Println(string(data))

}
func (s *EurekaStarter) Setup(ctx base.StarterContext) {
	info := make(map[string]interface{})
	info["startTime"] = time.Now()
	iiris.Iris().Get("/info", func(context iris.Context) {

		context.JSON(info)
	})
	iiris.Iris().Get("/health", func(context iris.Context) {
		health := eureka.Health{Details: make(map[string]interface{})}
		health.Status = eureka.StatusUp
		type DiskSpace struct {
			eureka.HealthStatus
			Total     uint64
			Free      uint64
			Threshold uint64
		}

		t, f, _ := DiskUsage("/")
		ds := DiskSpace{Total: t, Free: f, Threshold: 10485760}
		health.Details["diskSpace"] = ds

		context.JSON(health)
	})
}
func (s *EurekaStarter) Start(ctx base.StarterContext) {
	time.Sleep(5 * time.Second)
	s.client.UpdateStatus(s.client.InstanceInfo.AppName, s.client.InstanceInfo.InstanceId, eureka.StatusUp)
}
func (s *EurekaStarter) Stop(ctx base.StarterContext) {
	s.client.UnregisterInstance(s.client.InstanceInfo.AppName, s.client.InstanceInfo.InstanceId)
}

// disk usage of path/disk
func DiskUsage(path string) (uint64, uint64, uint64) {
	fs := syscall.Statfs_t{}
	err := syscall.Statfs(path, &fs)
	if err != nil {
		return 0, 0, 0
	}
	total := fs.Blocks * uint64(fs.Bsize)
	free := fs.Bfree * uint64(fs.Bsize)
	used := total - free
	return total, free, used
}

// NewClient create a basic client that is configured to be used
// with the given machine list.
func NewEurekaClient(conf kvs.ConfigSource) *eureka.Client {
	c := &config.EurekaConfig{
		Eureka: config.Eureka{
			Client:   config.NewEurekaClientConfig(),
			Instance: config.NewEurekaInstanceConfig(),
		},
	}

	err := conf.Unmarshal(c)
	if err != nil {
		panic(err)
	}

	//machines := []string{}
	//config := Config{
	//    // default timeout is one second
	//    DialTimeout: time.Second,
	//}
	//
	//client := &Client{
	//    Cluster: NewCluster(machines),
	//    Config:  config,
	//}
	//
	//client.initHTTPClient()
	//
	client := newClientbyConfig(c)
	return client
}

func newClientbyConfig(c *config.EurekaConfig) *eureka.Client {
	ins := eureka.CreateInstanceInfo(c)
	client := eureka.CreateEurekaClient(c.Eureka.Client)
	client.InstanceInfo = ins
	client.ClientConfig = &c.Eureka.Client
	client.InstanceConfig = &c.Eureka.Instance
	client.InstanceConfig.Appname = c.Application.Name
	return client
}
